import 'dart:async';
import 'dart:developer';

import 'package:baidu_trace/call_back.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';

import 'baidu_trace_platform_interface.dart';

/// An implementation of [BaiduTracePlatform] that uses method channels.
class MethodChannelBaiduTrace extends BaiduTracePlatform {
  /// The method channel used to interact with the native platform.
  @visibleForTesting
  final methodChannel = const MethodChannel('baidu_trace');

  final StreamController<BaiduListener> _streamController =
      StreamController<BaiduListener>.broadcast();

  StreamController<BaiduListener> get streamController => _streamController;

  @override
  Future<String?> getPlatformVersion() async {
    final version =
        await methodChannel.invokeMethod<String>('getPlatformVersion');
    return version;
  }

  @override
  Future<bool?> initSdk(Map<String,dynamic> args) async {
    return await methodChannel.invokeMethod<bool>('initSdk',args);
  }

  @override
  Future<bool?> stopGather() async {
    return await methodChannel.invokeMethod<bool>('stopGather');
  }

  @override
  Future<bool?> startGather() async {
    return await methodChannel.invokeMethod<bool>('startGather');
  }

  @override
  Future<bool?> stopTrace(int serviceId, String entityName) async {
    return await methodChannel.invokeMethod<bool>(
        'stopTrace', {'serviceId': serviceId, 'entityName': entityName});
  }

  @override
  Future<bool?> startTrace(int serviceId, String entityName) async {
    return await methodChannel.invokeMethod<bool>(
        'startTrace', {'serviceId': serviceId, 'entityName': entityName});
  }

  @override
  Future<bool?> updateEntity(int tag, int serviceId, String entityName,
      {String? entityDesc, Map<String, String>? columns}) async {
    return await methodChannel.invokeMethod<bool>('updateEntity', {
      'tag': tag,
      'serviceId': serviceId,
      'entityName': entityName,
      'entityDesc': entityDesc,
      'columns': columns
    });
  }

  @override
  Future<bool?> addEntity(int tag, int serviceId, String entityName,
      {String? entityDesc, Map<String, String>? columns}) async {
    return await methodChannel.invokeMethod<bool>('addEntity', {
      'tag': tag,
      'serviceId': serviceId,
      'entityName': entityName,
      'entityDesc': entityDesc,
      'columns': columns
    });
  }

  @override
  void setTraceListener() {
    methodChannel.setMethodCallHandler((call) {
      log('setMethodCallHandler--$call');
      _streamController.add(BaiduListener(
          method: call.method,
          status: call.arguments['status'] ?? 1,
          message: call.arguments['message']));
      return Future(() => null);
    });
  }

  @override
  Stream<BaiduListener> getStream() {
    return streamController.stream;
  }
}
